package com.e0box.game.logicGraphics.data
{
	import com.e0box.game.logicGraphics.display.Tile;
	
	public class TileMap
	{
		private var _map:Vector.<Vector.<Tile>>;;
		
		private var _width:uint;
		private var _height:uint;
		
		public function TileMap(width:uint, height:uint)
		{
			_width = width;
			_height = height;
			
			init();
		}
		
		private function init():void
		{
			_map = new Vector.<Vector.<Tile>>();
			var tile:Tile;
			for(var i:uint = 0; i < _height; i++)
			{
				_map[i] = new Vector.<Tile>();
				
				for(var j:uint = 0; j < _width; j++)
				{
					tile = Tile.getTile();
					tile.tileX = j;
					tile.tileY = i;
					
					_map[i].push(tile);
				}
			}
		}
		
		public function output():Vector.<Vector.<uint>>
		{
			var result:Vector.<Vector.<uint>> = new Vector.<Vector.<uint>>();
			
			for(var i:uint = 0; i < _height; i++)
			{
				result.push(new Vector.<uint>());
				for(var j:uint = 0; j < _width; j++)
				{
					result[i][j] = _map[i][j].output();
				}
			}
			
			return result;
		}
		
		public function resize(width:uint, height:uint):void
		{
			var forHeight:uint = Math.max(height, _height);
			
			var row:Vector.<Tile>;
			var tile:Tile;
			for(var i:uint = 0; i < forHeight; i++)
			{
				if(i > _height - 1)
				{
					_map.push(new Vector.<Tile>());
				}else if(i > height - 1)
				{
					row = _map.pop();
					while(row.length)
					{
						row.pop().free();
					}
					continue;
				}
				
				row = _map[i];
				if(row.length < width)
				{
					while(row.length < width)
					{
						tile = Tile.getTile();
						tile.tileX = row.length;
						tile.tileY = i;
						
						row.push(tile);
					}
				}
				else
				{
					while(row.length > width)
					{
						row.pop().free();
					}
				}
			}
			
			_width = width;
			_height = height;
			
			clearAllTilesState();
		}
		
		public function clearAllTilesState():void
		{
			for(var i:uint = 0; i < _height; i++)
			{
				for(var j:uint = 0; j < _width; j++)
				{
					_map[i][j].setState(Tile.STATE_BLANK);
				}
			}
		}
		
		public function getTile(x:uint, y:uint):Tile
		{
			if(x >= _width || y >= _height)
			{
				return null;
			}
			
			return _map[y][x];
		}
		
		public function get width():uint
		{
			return _width;
		}
		
		public function get height():uint
		{
			return _height;
		}
		
		public function getColTip(col:uint, reverse:Boolean = false, autoBreak:Boolean = false):Vector.<uint>
		{
			var result:Vector.<uint> = new Vector.<uint>();
			
			var state:uint;
			var count:uint = 0;
			
			var i:int;
			
			if(reverse)
			{
				for(i = height - 1; i >= 0; i--)
				{
					state = _map[i][col].getState();
					if(state == Tile.STATE_BLOCK)
					{
						count++;
					}
					else if(state == Tile.STATE_BLANK)
					{
						if(count > 0)
						{
							result.push(count);
							count = 0;
						}
					}
					else
					{
						if(autoBreak)
						{
							return result;
						}
						count++;
					}
				}
				
				if(count > 0)
				{
					result.push(count);
					count = 0;
				}
			}
			else
			{
				for(i = 0; i < height; i++)
				{
					state = _map[i][col].getState();
					if(state == Tile.STATE_BLOCK)
					{
						count++;
					}
					else if(state == Tile.STATE_BLANK)
					{
						if(count > 0)
						{
							result.push(count);
							count = 0;
						}
					}
					else
					{
						count++;
					}
				}
				
				if(count > 0)
				{
					result.push(count);
					count = 0;
				}
			}
			
			return result;
		}
		
		public function getTopTip():Vector.<Vector.<uint>>
		{
			var result:Vector.<Vector.<uint>> = new Vector.<Vector.<uint>>();
			for(var i:uint = 0; i < width; i++)
			{
				result.push(getColTip(i));
//				trace(i, "        ", result[i]);
			}
			return result;
		}
		
		public function getRowTip(row:uint, reverse:Boolean = false, autoBreak:Boolean = false):Vector.<uint>
		{
			var result:Vector.<uint> = new Vector.<uint>();
			
			var state:uint;
			var count:uint = 0;
			
			var i:int;
			
			if(reverse)
			{
				for(i = width - 1; i >= 0; i--)
				{
					state = _map[row][i].getState();
					if(state == Tile.STATE_BLOCK)
					{
						count++;
					}
					else if(state == Tile.STATE_BLANK)
					{
						if(count > 0)
						{
							result.push(count);
							count = 0;
						}
					}
					else
					{
						count++;
					}
				}
				
				if(count > 0)
				{
					result.push(count);
					count = 0;
				}
			}
			else
			{
				for(i = 0; i < width; i++)
				{
					state = _map[row][i].getState();
					if(state == Tile.STATE_BLOCK)
					{
						count++;
					}
					else if(state == Tile.STATE_BLANK)
					{
						if(count > 0)
						{
							result.push(count);
							count = 0;
						}
					}
					else
					{
						if(autoBreak)
						{
							return result;
						}
						
						count++;
					}
				}
				
				if(count > 0)
				{
					result.push(count);
					count = 0;
				}
			}
			
			
			return result;
		}
		
		public function getLeftTip():Vector.<Vector.<uint>>
		{
			var result:Vector.<Vector.<uint>> = new Vector.<Vector.<uint>>();
			
			for(var i:uint = 0; i < height; i++)
			{
				result.push(getRowTip(i));
//				trace(i,"       ",result[i]);
			}
			
			return result;
		}
		
		/*public function get map():Vector.<Vector.<Tile>>{
			return _map;
		}*/
	}
}